#include "BlockQueue.hpp"
#include <unistd.h>
#include "Task.hpp"
#include <ctime>

// 消费者
void *Consumer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    while (true)
    {
        // 消费者每隔一秒消费一次
        // sleep(1);
        // 消费行为 - 将数据放到阻塞队列里
        Task t = bq->pop();
        // 计算
        t.run();
        std::cout << "线程" << pthread_self() << "正在处理任务：" << t.GetTask() << " 运算结果是: " << t.GetRusult() << std::endl;
        std::cout << "------------------------" << std::endl;
    }
}

// 生产者
void *Producter(void *args)
{
    int len = oper.size();
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    int data = 0;
    while (true)
    {
        // 生产行为 - 获取阻塞队列的数据
        int data1 = rand() % 10 + 1; // 数据范围[1, 10]
        int data2 = rand() % 10 + 1;
        char op = oper[rand() % len];
        Task t(data1, data2, op);
        usleep(10); // 模拟生产者获取数据。休眠10微秒，即0.00001秒

        // 生产者每隔一秒生产一次
        sleep(1);
        bq->push(t);
        std::cout << "线程" << pthread_self() << "生产了一个任务: " << t.GetTask() << std::endl;
        std::cout << "------------------------" << std::endl;
        sleep(1);
    }
}

int main()
{
    // 随机数种子
    srand(time(nullptr));
    // 阻塞队列
    BlockQueue<Task> *bq = new BlockQueue<Task>();

    // c - 消费者线程
    // p - 生产者线程
    pthread_t c[3], p[5];
    for (int i = 0; i < 3; i++)
    {
        pthread_create(c + i, nullptr, Consumer, (void *)bq);
    }
    for (int i = 0; i < 5; i++)
    {
        pthread_create(p + i, nullptr, Producter, (void *)bq);
    }

    // 主线程负责等待cp线程
    for (int i = 0; i < 3; i++)
    {
        pthread_join(c[i], nullptr);
    }
    for (int i = 0; i < 5; i++)
    {
        pthread_join(p[i], nullptr);
    }
    delete bq;
    return 0;
}

// ============================== 单生产单消费模型测试代码 ========================
// #include "BlockQueue.hpp"
// #include <unistd.h>
// #include "Task.hpp"
// #include <ctime>

// // 消费者
// void *Consumer(void *args)
// {
//     BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
//     while (true)
//     {
//         // 消费者每隔一秒消费一次
//         // sleep(1);
//         // 消费行为 - 将数据放到阻塞队列里
//         Task t = bq->pop();
//         // 计算
//         t.run();
//         std::cout << "处理任务：" << t.GetTask() << " 运算结果是: " << t.GetRusult() << std::endl;
//         std::cout << "------------------------" << std::endl;
//     }
// }

// // 生产者
// void *Producter(void *args)
// {
//     int len = oper.size();
//     BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
//     int data = 0;
//     while (true)
//     {
//         // 生产行为 - 获取阻塞队列的数据
//         int data1 = rand() % 10 + 1; // 数据范围[1, 10]
//         int data2 = rand() % 10 + 1;
//         char op = oper[rand() % len];
//         Task t(data1, data2, op);
//         usleep(10); // 模拟生产者获取数据。休眠10微秒，即0.00001秒

//         // 生产者每隔一秒生产一次
//         sleep(1);
//         bq->push(t);
//         std::cout << "生产了一个任务: " << t.GetTask() << std::endl;
//         std::cout << "------------------------" << std::endl;
//     }
// }

// int main()
// {
//     // 随机数种子
//     srand(time(nullptr));
//     // 阻塞队列
//     BlockQueue<Task> *bq = new BlockQueue<Task>();

//     // c - 消费者线程
//     // p - 生产者线程
//     pthread_t c, p;
//     pthread_create(&c, nullptr, Consumer, (void *)bq);
//     pthread_create(&p, nullptr, Producter, (void *)bq);

//     // 主线程负责等待cp线程
//     pthread_join(c, nullptr);
//     pthread_join(p, nullptr);

//     return 0;
// }